iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0

接下來我們終於要來製作一直放著的標籤相關功能的內容,當我們的blog內容變多的時候,我們可以添加一個標籤的功能,讓使用者點擊標籤的時候,就可以得到擁有該標籤所有文章,在這過程中我們會用到動態路由的方式去呈現

https://ithelp.ithome.com.tw/upload/images/20241004/20169170U33o0pgW7M.png

我們移除了舊的tag頁面,並且在pages裡面新增了一個tags的資料夾,裡面建立了一個名為[tag].astro的檔案,這個檔案中的[tag],將會變成我們未來點擊標籤時所提供的參數,在[tag].astro的檔案中我們寫了之前寫好的布局,並且從astro.prams中提取出來名為tags的變數,而posts將會是我們文章的來源

值得一提的是psot的文章用props的方式去取得資料,但我們的文章應該是要根據我們所選擇的tag去做篩選,而不是用父元件傳參數的方式去執行,那麼我們該怎麼做呢?

https://ithelp.ithome.com.tw/upload/images/20241004/20169170HIOkdh9n4y.png

可以看到圖片中寫了一個非同步的async function,接下來我們要來逐步講解裡面的內容:

const allPosts = await Astro.glob('../posts/*.md');
  • 使用 Astro.glob 方法異步地讀取 ../posts/ 目錄下的所有 .md 文件。這些 Markdown 文件會被解析為包含 frontmattercontent 的物件。allPosts 是一個包含所有文章(Markdown 文件)物件的陣列。
const tags = allPosts.map((post) => post.frontmatter.tags);
  • 使用 map() 方法遍歷 allPosts 陣列,並從每篇 post 物件的 frontmatter 中提取出 tagsfrontmatter 是每篇 Markdown 文件原本的資料(如標題、標籤等)。結果會是一個二維陣列(陣列中還有陣列),每篇文章都包含自己的標籤陣列。
const flatTags = tags.flat();
  • flat() 方法將二維陣列轉換為一維陣列。因為 tags 是一個二維陣列(每篇文章有多個標籤),所以這一步會將它展平成一個一維的標籤陣列。
uniqueTags = [...new Set(flatTags)];
  • 因為每篇文章都會自己的標籤,展平之後會把所有的陣列變成一個陣列,這樣子就會出現每個文章的所有標籤,導致會有重複的情形出現,故使用 Set 來移除重複的標籤。Set 是一種只允許唯一值的資料結構,將 flatTags 放進 Set 之後,自動移除了重複的標籤。然後使用 [...new Set(flatTags)] 將其轉換回普通陣列 uniqueTags,這個陣列只包含不重複的標籤。
return uniqueTags.map((tag) => 

const filteredPosts = allPosts.filter((post) => post.frontmatter.tags.includes(tag));
  • 使用 filter() 方法從 allPosts 中篩選出包含當前標籤 tag 的文章。post.frontmatter.tags.includes(tag) 檢查該篇文章的標籤數組中是否包含當前的標籤 tagfilteredPosts 是一個包含所有符合該標籤的文章的陣列。
return { params: { tag }, props: { posts: filteredPosts } };
  • map() 返回一個物件,包含兩個屬性:
    • params:指定動態路徑的參數(即當前的標籤 tag)。在 Astro 中,動態路由可以生成 /tags/[tag] 形式的 URL。
    • props:傳遞給該頁面的屬性。這裡傳遞的是 posts,即包含當前標籤 tag 的文章。

總結:

  1. 讀取所有 .md 文件。
  2. 提取所有文章中的標籤。
  3. 移除重複的標籤。
  4. 為每個唯一標籤生成靜態頁面的路徑。
  5. 根據標籤篩選對應的文章,並將文章作為 props 傳遞給靜態頁面。

接下來讓我們測試一下結果

https://ithelp.ithome.com.tw/upload/images/20241004/201691705jatFZ2djq.png

可以看到我們在網址上面改成了”tags/我們想要的標籤”,那麼我們的頁面就會幫我們過濾含有該標籤的文章,這樣我們就實現了過濾文章的功能了!


上一篇
和2魚坐牢的第二十四天-Astro之動態獲取文章
下一篇
和2魚坐牢的第二十五天-Astro之標籤頁建立2
系列文
和鱷魚組長的坐牢30天之vue的簡易todolist和Astro的簡易部落格實現30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言